<?php
/*********************************************
 *  CPG Dragonfly™ CMS
 *********************************************
	Copyright © since 2010 by CPG-Nuke Dev Team
	http://dragonflycms.org

	Dragonfly is released under the terms and conditions
	of the GNU GPL version 2 or any later version
*/

namespace Poodle\Crypt;

class Mcrypt extends \Poodle\Crypt_Base
{

	public static function listCiphers() { $list=mcrypt_list_algorithms();sort($list);return $list; }
	public static function listModes()   { return mcrypt_list_modes(); }

	public function Encrypt(&$Data, $WeakKey)
	{
		# Convert data into a serialized string for single packing
		$SecretData = serialize($Data);
		# handle potential compression
		$this->compressor($SecretData);
		# Open the cipher module
		$mc   = mcrypt_module_open($this->options['cipher'], '', $this->options['mode'], '');
		if (!$mc) { return false; }
		# Harden key data into safe key
		$key  = substr(sha1($this->options['salt'] . $WeakKey), 0, mcrypt_enc_get_key_size($mc));
		# Get the size of the appropriate local initialization vector
		$ivsz = mcrypt_enc_get_iv_size($mc);
		# Generate an initialization vector
		# NEVER USE MCRYPT_DEV_RANDOM! It might be very slow due to the nature of /dev/random entropy
		$iv   = mcrypt_create_iv($ivsz, MCRYPT_DEV_URANDOM);
		if (!$iv) { mcrypt_module_close($mc); return false; }
		# Init encryption engine
		mcrypt_generic_init($mc, $key, $iv);
		# Perform encryption
		$encrypted = mcrypt_generic($mc, $SecretData);
		# Shut down encryption engine and close the cipher module
		mcrypt_generic_deinit($mc);
		mcrypt_module_close($mc);
		# Return the IV prepended to the data stream, CBC tamper protected
		$encrypted = $iv.$encrypted;
		return $this->Scramble($encrypted, $key);
	}

	public function Decrypt(&$SecretData, $WeakKey)
	{
		# Open the cipher module
		$mc   = mcrypt_module_open($this->options['cipher'], '', $this->options['mode'], '');
		if (!$mc) { return false; }
		# Regenerate hardened key from weak key
		$key  = substr(sha1($this->options['salt'] . $WeakKey), 0, mcrypt_enc_get_key_size($mc));
		# Remove leading-block CBC tampering attack protection
		$data = $this->Descramble($SecretData, $key);
		# Get the size of the appropriate local initialization vector
		$ivsz = mcrypt_enc_get_iv_size($mc);
		# Recover the initialization vector
		$iv   = substr($data, 0, $ivsz);
		# Recover the data block
		$data = substr($data, $ivsz);
		# Init decryption engine
		mcrypt_generic_init($mc, $key, $iv);
		# Perform decryption
		$data = mdecrypt_generic($mc, $data);
		# Shut down decryption engine and lose the cipher module
		mcrypt_generic_deinit($mc);
		mcrypt_module_close($mc);
		# handle potential decompression
		$this->compressor($data, true);
		# Convert data from a serialized string and return
		return unserialize($data);
	}

}
